package com.hl.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.hl.entity.Customer;
import com.hl.mapper.CustomerMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
public class CustomerListener extends AnalysisEventListener<Customer> {
    
    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 100;
    
    private List<Customer> etfBigCustomerList = new ArrayList<>();
    
    private final CustomerMapper customerMapper;
    
    
    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     */
    public CustomerListener(CustomerMapper customerMapper) {
        this.customerMapper = customerMapper;
    }
    
    @SneakyThrows
    @Override   // 解析到 第一列 可以判断 指定字段 是否存在
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        log.info("解析到一条头数据:{}", JSON.toJSONString(headMap));
        if (!headMap.containsValue("memberId")) {
            throw new Exception("the file has no memberId");
        }
        
    }
    
    @Override
    public void invoke(Customer etfBigCustomer, AnalysisContext analysisContext) {
        etfBigCustomerList.add(etfBigCustomer);
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (etfBigCustomerList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            etfBigCustomerList.clear();
        }
    }
    
    
    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();
        log.info("data analyse finish!");
    }
    
    /**
     * 存储数据库
     */
    private void saveData() {
        if (CollectionUtils.isEmpty(etfBigCustomerList)) {
            log.info("The list is empty");
            return;
        }
        log.info("{} count menu data, start to save mysql", etfBigCustomerList.size());
        customerMapper.insertList(etfBigCustomerList);
    }
}
